package pl.edu.pw.elka.dzielins.revanalyzer.model;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import edu.mit.csail.sdg.alloy4compiler.ast.Sig;

public class ModelObject {
	private String name;
	private Sig sig;
	private ModelObject baseObject;
	private Set<ModelRelation> relations;

	public ModelObject() {
		this.relations = new HashSet<ModelRelation>();
	}

	// getters & setters

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Sig getSig() {
		return sig;
	}

	public void setSig(Sig sig) {
		this.sig = sig;
	}

	public ModelObject getBaseObject() {
		return baseObject;
	}

	public void setBaseObject(ModelObject baseObject) {
		this.baseObject = baseObject;
	}

	/**
	 * 
	 * @return List of
	 *         {@link pl.edu.pw.elka.dzielins.revanalyzer.model.ModelRelation
	 *         ModelRelation} objects from this ModelObject objects.
	 *         {@link pl.edu.pw.elka.dzielins.revanalyzer.model.ModelRelation
	 *         ModelRelation} objects from base object are not included.
	 */
	public Set<ModelRelation> getRelations() {
		return relations;
	}

	public void setRelations(Set<ModelRelation> relations) {
		this.relations = relations;
	}

	// artificial getters & setters

	public boolean isTopLevel() {
		return (baseObject == null);
	}
	
	public Set<ModelRelation> getAllRelations() {
		Set<ModelRelation> relations = this.relations;
		if (baseObject!=null)
			relations.addAll(baseObject.getAllRelations());
		return relations;
	}

	/**
	 * 
	 * @param name
	 *            Relation name.
	 * @return {@link pl.edu.pw.elka.dzielins.revanalyzer.model.ModelRelation
	 *         ModelRelation} object with given name or null when it is not
	 *         found.
	 */
	public ModelRelation getRelation(String name) {
		for (ModelRelation relation:getAllRelations())
			if (relation.getName().equals(name))
				return relation;
		return null;
	}

	// other methods

	public boolean inherits(ModelObject from) {
		if (from == null || getBaseObject() == null)
			return false;

		return (getBaseObject() == from || getBaseObject().inherits(from));
	}

	public boolean inherits(String fromName) {
		if (StringUtils.isBlank(fromName) || getBaseObject() == null)
			return false;

		return (getBaseObject().getName().equals(fromName) || getBaseObject().inherits(fromName));
	}

	@Override
	public String toString() {
		return getName();
		/*String s;
		s = getName();
		if (baseObject != null)
			s += " extends " + baseObject.getName();
		Set<ModelRelation> rels = getAllRelations();
		if (rels != null && !rels.isEmpty()) {
			s += " {\n";
			for (ModelRelation relation : rels)
				s += "\t" + relation.toString() + "\n";
		} else
			s += " { ";
		s += "}";
		return s;*/
	}
}
